﻿using System.IO;
using System.Text;
using System.Windows.Forms;
using Microsoft.Reporting.WinForms;
using clasesBase;

namespace PlanificacionProduccion
{
    public class Impresion
    {
        private Stream flujoDatos;
        private string pathArchivo = "";

        #region Métodos de impresión públicos
        public void imprimirReporte(string nombreTabla, BindingSource bindingDatos, string nombreReporte, bool generarPDF, bool generarXLS, Cursor mouse, string nombreCompletoArchivo, bool mostrarResultado, ReportParameter[] parametrosReporte, SubreportProcessingEventHandler manejadorInformeIntegrado, IWin32Window propietario)
        {
            // Se define la modalidad del cursor: cursor en espera para indicar al usuario que se está trabajando
            mouse = Cursors.WaitCursor;

            // Se crea el informe con la información pasada como parámetro: el nombre de la tabla que usa el reporte, los datos a mostrarse,
            // el nombre del reporte que se desea abrir y los parámetros en caso que tenga (en otro caso debe enviarse null)
            FrmReporte inform = generarInformeBasico(nombreTabla, bindingDatos, nombreReporte);

            // Si el arreglo de parámetros no es nulo, entonces se lo setea al informe ya que significa que existen parámetros asociados.
            if (parametrosReporte != null) inform.Report_viewer.LocalReport.SetParameters(parametrosReporte);

            // Si el manejador de informes integrados no es nulo, entonces se lo asigna al informe para que de esta manera se los pueda manejar correctamente.
            if (manejadorInformeIntegrado != null) inform.Report_viewer.LocalReport.SubreportProcessing += manejadorInformeIntegrado;

            // Se puede mostrar el reporte de impresión o bien generar un PDF directamente con la info del reporte
            if (generarPDF || generarXLS)
            {
                string tipoArchivoSalida = generarPDF ? "PDF" : "Excel";

                // Si no se indicó un nombre particular (ruta completa) para el archivo (PDF o XLS), entonces se abrirá una ventana de diálogo para solicitar
                // al usuario que elija la ubicación donde desea guardarlo.
                if (nombreCompletoArchivo.Trim() == "") pathArchivo = ManejadorPath.obtenerRutaGuardarArchivo("", tipoArchivoSalida);
                else pathArchivo = nombreCompletoArchivo.Trim();

                if (pathArchivo != "")
                {
                    ExportarArchivo(inform.Report_viewer.LocalReport, tipoArchivoSalida);

                    mouse = Cursors.Default;

                    // Si se desea, se puede mostrar un mensaje del resultado del proceso en este punto. Caso contrario, puede mostrarse desde el
                    // método que llamó a éste.
                    //if (mostrarResultado) MessageBox.Show(string.Format("Se ha exportado correctamente a {0}.", tipoArchivoSalida), "Exportar archivo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    if (mostrarResultado) System.Diagnostics.Process.Start(pathArchivo);
                }
            }
            else
            {
                mouse = Cursors.Default;
                inform.ShowDialog(propietario);
            }
        }
        #endregion

        #region Método auxiliares de impresión, privados
        private FrmReporte generarInformeBasico(string nombreTabla, BindingSource bindingDatos, string nombreReporte)
        {
            FrmReporte inform = new FrmReporte(nombreTabla);
            inform.Datos.DataSource = bindingDatos.DataSource;
            inform.Report_viewer.LocalReport.ReportEmbeddedResource = nombreReporte;

            return inform;
        }

        private void ExportarArchivo(LocalReport reporte, string tipoSalida)
        {
            string infoDispositivo = "";
            Warning[] advertencias;
            string tipo = tipoSalida.Trim().ToUpper().Equals("PDF") ? "PDF" : "Excel";

            reporte.Render(tipo, infoDispositivo, crearFlujoDatos, out advertencias);
            flujoDatos.Close();
        }

        private Stream crearFlujoDatos(string nombre, string extensionArchivo, Encoding codificacion, string mimeType, bool willSeek)
        {
            flujoDatos = new FileStream(pathArchivo, FileMode.Create);
            return flujoDatos;
        }
        #endregion
    }
}
